package starComponent.parallelcoordinates;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RadialGradientPaint;
import java.awt.event.InputEvent;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;

import starComponent.controls.ObserverThumb;
import starComponent.elements.A_StarBranch;
import starComponent.elements.A_Thumb;
import starComponent.experiments.expeComparison.Validator;
import tuio.AcceleratedTouchEvent;
import tuio.TCurAndPoint;
import tuio.components.LabelTouch;

/**
 * @author Charles Perin
 * 12 avr. 2011
 * LIMSI - INRIA Rennes
 * charles.perin@free.fr
 */
public class ParallelThumb extends A_Thumb{

	private static final long serialVersionUID = -4571471888727685164L;

	public ParallelThumb(A_ParallelBranch branch){
		super(branch);
	}

	public void initPosition(){
		
		xPos = (int) (((A_ParallelBranch)branch).getX());
		yPos = (int) (-value*branch.getLength()/branch.getMax()+((A_ParallelBranch)branch).getyStart());

		this.setBounds(xPos-THUMB_SIDE/2, yPos-THUMB_SIDE/2, THUMB_SIDE, THUMB_SIDE);
		this.center = new Point(this.getX()+this.getWidth()/2,this.getY()+this.getHeight()/2);

		checkSnapToTick();
	}


	private void checkSnapToTick(){
		if(branch.isSnapToTicks()){
			HashMap<Double, ParallelLadderTick> safeMap = new HashMap<Double, ParallelLadderTick>(((A_ParallelBranch)branch).getLadder().getLadderMap());
			ParallelLadderTick closer = null;
			double distToCloser = Double.MAX_VALUE;

			synchronized (safeMap) {
				Iterator<Double> iter = safeMap.keySet().iterator();
				while(iter.hasNext()){
					Double key = iter.next();
					ParallelLadderTick current = safeMap.get(key);
					double distToCurrent = Math.sqrt(Math.pow(Math.abs(center.getX()-current.getxCenter()),2)+Math.pow(Math.abs(center.getY()-current.getyCenter()), 2));
					if(distToCurrent<distToCloser){
						distToCloser = distToCurrent;
						closer = current;
					}
				}
			}

			if(closer != null){
				this.setBounds(closer.getxCenter()-THUMB_SIDE/2, closer.getyCenter()-THUMB_SIDE/2, THUMB_SIDE, THUMB_SIDE);
				this.center = new Point(this.getX()+this.getWidth()/2,this.getY()+this.getHeight()/2);

				value = closer.getValue();
			}
		}
	}


	@Override
	public void paint(Graphics g){
		Graphics2D g2d = (Graphics2D)g;

		if(isSelected)g2d.setPaint(new RadialGradientPaint(new Point(this.getWidth()/2, this.getHeight()/2), 10, new float[]{0.2f, 1f}, thumbSelectedColor));
		else g2d.setPaint(new RadialGradientPaint(new Point(this.getWidth()/2, this.getHeight()/2), 10, new float[]{0.2f, 1f}, thumbColor));
		g2d.fillOval(this.getWidth()/2-THUMB_SIDE/4, this.getHeight()/2-THUMB_SIDE/4, THUMB_SIDE/2, THUMB_SIDE/2);
	}

	@Override
	public void checkNewPosition(int x, int y) {
		
		double yReal;
		yReal = y;
		if(((A_ParallelBranch)branch).pointIsInBranch(x, y)){
			boolean isValMin=false;
			if(y>((A_ParallelBranch)branch).getyStart())isValMin = true;
			double dist=0;
			if(!isValMin) dist = Math.abs(((A_ParallelBranch)branch).getyStart()-yReal);

			double tmpValueOnBranch = value;
			//si bislider
			if(branch instanceof ParallelBranchBiSlider){
				ParallelBranchBiSlider bislider = (ParallelBranchBiSlider)branch;
				tmpValueOnBranch = dist*(branch.getMax()-branch.getMin())/branch.getLength();
				tmpValueOnBranch = Math.min(tmpValueOnBranch, branch.getMax());
				if(this == bislider.getThumbStart()){
					if(bislider.getMaxValue()-tmpValueOnBranch<bislider.getMinRange()){
						tmpValueOnBranch = bislider.getMaxValue()-bislider.getMinRange();
					}
				}
				else{
					if(tmpValueOnBranch-bislider.getMinValue()<bislider.getMinRange()){
						tmpValueOnBranch = bislider.getMinValue()+bislider.getMinRange();
					}
				}
			}
			//si slider
			else if(branch instanceof ParallelBranchSlider){
				tmpValueOnBranch = dist*(branch.getMax()-branch.getMin())/branch.getLength();
				tmpValueOnBranch = Math.min(tmpValueOnBranch, branch.getMax());
			}

			value = tmpValueOnBranch;
			
			yPos = (int) (-value*branch.getLength()/branch.getMax()+((A_ParallelBranch)branch).getyStart());

			this.setLocation(xPos-THUMB_SIDE/2, yPos-THUMB_SIDE/2);

			center = new Point(this.getX()+this.getWidth()/2,this.getY()+this.getHeight()/2);

			checkSnapToTick();

			updateObserverThumb();

			getParent().getParent().repaint();

		}


	}


	public void setValue(double value) {
		this.value = value;
		initPosition();
		updateObserverThumb();
	}

}
